import os
import re
import logging
from pathlib import Path

import numpy as np
from moviepy import VideoFileClip

import pandas as pd
from pandas import Series, DataFrame

import common.utils
# from tools import _get_files_name as get_files_name
from tools import merge_student_dataframes
from tools import convert_mmdd_to_date
from common import utils
from file import get_files_name
from file import has_duplicates

from Basic import Basic

文档 = '([^-\.]+)'
班级 = '([^-\.]+)'
学号 = '([0-9]{11})'
姓名 = '([^-\.]+)'
日期 = '([0-9]{4})'
时长 = '([0-9]+)'
后缀 = '([^-\.]+)'

logging.basicConfig(
    level=logging.DEBUG,
    format='%(levelname)8s: %(message)s'
)

# BASE_PATH = r"D:\100-Project\2025-2026-1学期安排\首义学院\19201017_《企业级应用开发课程设计（企业）》"
# FOLDER_PATH = f"{BASE_PATH}\学生提交\视频"
FILE_TYPES = ['.mp4', '.mkv']
PATTERN_视频_1 = f'^{班级}-{学号}-{姓名}.{日期}.{后缀}$'
PATTERN_视频_2 = f'^{班级}-{学号}-{姓名}.{日期}_{时长}.{后缀}$'


class 课设视频(Basic):

    # 初始化方法（构造函数），用于创建实例时初始化属性
    def __init__(self):
        super().__init__()  # 调用父类的初始化方法

        self.name_sheet_file_path = f"{self.base_path}\学生提交\学生名单.xlsx"
        self.folder_path = f"{self.base_path}\学生提交\视频"
        self.output_file = f"{self.base_path}\学生提交\视频.xlsx"

        self.filenames: Series = pd.Series(dtype=str)
        self.ids = pd.Series(dtype=int)
        self.names = pd.Series(dtype=str)

        self.stu_list: DataFrame = pd.DataFrame(columns=['学号', '姓名'])
        self.commited_list: DataFrame = pd.DataFrame(columns=['学号', '姓名', '日期', '时长', '答辩情况', '设计成果'])
        self.all_list: DataFrame = pd.DataFrame(columns=['学号', '姓名', '日期', '答辩情况', '设计成果'])

    def get_folder_path(self):
        # 子类必须实现父类的抽象方法
        return self.folder_path

    def get_stu_name_sheet_file_path(self):
        # 子类必须实现父类的抽象方法
        return self.name_sheet_file_path

    def get_file_types(self) -> list:
        return ['.mp4', '.mkv']

    def get_commited_list(self) -> DataFrame:
        logging.debug("统计已提交的学生记录")

        self.check_filenames_format(PATTERN_视频_2)
        self.check_filenames_duplicates()

        se_学号 = self.extract_parts_from_filename(PATTERN_视频_2, 2).astype(int)
        se_姓名 = self.extract_parts_from_filename(PATTERN_视频_2, 3).astype(str)
        se_日期 = self.extract_parts_from_filename(PATTERN_视频_2, 4).astype(str)
        se_时长 = self.extract_parts_from_filename(PATTERN_视频_2, 5).astype(int)

        # region 答辩情况
        # 定义目标区间 (10, 50)
        se_时长 = self.fix_时长(se_时长)
        min_target = 20
        max_target = 50

        # 计算原始数据的最小值和最大值
        min_x = se_时长.min()
        max_x = se_时长.max()
        se_scaled = min_target + (se_时长 - min_x) * (max_target - min_target) / (max_x - min_x)
        # print(se_scaled.astype(int))
        se_答辩情况 = se_scaled.astype(int)

        # endregion

        # region 设计成果
        se_设计成果 = self.round_up_to_5_with_limit(se_答辩情况 + 7, 48)
        # endregion

        df_merged = pd.DataFrame({
            '学号': se_学号,
            '姓名': se_姓名,
            '日期': se_日期,
            '时长': se_时长,
            '答辩情况': se_答辩情况,
            '设计成果': se_设计成果
        })
        self.commited_list = df_merged

        return self.commited_list

    def get_all_list(self) -> DataFrame:
        logging.debug("统计所有学生记录")

        df_stu_list = self.get_stu_list()
        df_commited_list = self.get_commited_list()
        df_commited_list = df_commited_list[['学号', '日期', '答辩情况', '设计成果']]

        merged_df = pd.merge(
            df_stu_list,  # 左表
            df_commited_list,  # 右表
            on='学号',  # 关联列（必须在两表中都存在）
            how='left',  # 左连接方式
            suffixes=('_left', '_right')  # 解决同名列冲突（如 bbb 在两表都存在）
        )

        self.all_list = merged_df
        return self.all_list

    def round_up_to_5_with_limit(self, s: Series, upper) -> pd.Series:
        """
        将整数Series向上取整到最近的5的倍数，且结果不超过upper

        参数:
            s: 输入的整数类型Series

        返回:
            处理后的Series，值为5的倍数且≤48
        """
        # 向上取整到5的倍数
        rounded = (s / 5).apply(np.ceil) * 5
        # 限制最大值为48
        rounded = rounded.clip(upper=upper)
        # 转换回整数类型
        return rounded.astype(int)


if __name__ == "__main__":
    课设视频 = 课设视频()
    # df = 课设视频.get_commited_list()
    df = 课设视频.get_all_list()

    min_答辩情况 = df['答辩情况'].min()
    min_设计成果 = df['设计成果'].min()
    df['答辩情况'] = df['答辩情况'].fillna(min_答辩情况 - 1)
    df['设计成果'] = df['设计成果'].fillna(min_设计成果 - 1)
    print(df)

    df.to_excel(课设视频.output_file, index=False)
    print(f"✅ 数据合并完成! 文件已保存至: {课设视频.output_file}")
